﻿#include "pch.h"
#include "tgsdkmanager.h"
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>
#ifdef _WIN32
#include <Windows.h>
#else
#include <dlfcn.h>
#include <unistd.h>
#endif
#include "JsonUtils.hpp"
#include "ConvertUtils.h"

TG_OnHIDListener TGSDKManager::m_TG_OnHIDListener = nullptr;
TG_OnFrameListener TGSDKManager::m_TG_OnFrameListener = nullptr;
TG_OnReadFileListener TGSDKManager::m_TG_ReadFileListener = nullptr;
TG_WriteFileListener TGSDKManager::m_TG_WriteFileListener = nullptr;
TG_WriteRandomFileListener TGSDKManager::m_TG_WriteRandomFileListener = nullptr;
TG_ReadRandomFileListener TGSDKManager::m_TG_ReadRandomFileListener = nullptr;

// 报码回调
TUP_Barcode_Result_Callback TGSDKManager::m_TUPBarCodeResultCallback = nullptr;
// 分辨率回调
TUP_Resolution_Callback TGSDKManager::m_TUPResolutionCallback = nullptr;

TGSDKManager::TGSDKManager() {
  std::cout << "TGSDKManager::TGSDKManager()" << std::endl;
  InitHID();
}

TGSDKManager::~TGSDKManager() {
  std::cout << "TGSDKManager::~TGSDKManager()" << std::endl;
  m_pHidEngine.reset();
  m_OnErrorListener.reset();
  m_FrameListener.reset();
  m_ReadFileListener.reset();
  m_StopDataListener.reset();
  m_WriteListener.reset();
  m_WriteRandomFileListener.reset();

  TGSDKManager::m_TG_WriteFileListener = nullptr;
  TGSDKManager::m_TG_OnFrameListener = nullptr;
  TGSDKManager::m_TG_ReadFileListener = nullptr;
  TGSDKManager::m_TG_OnHIDListener = nullptr;
  TGSDKManager::m_TG_WriteRandomFileListener = nullptr;
  TGSDKManager::m_TG_ReadRandomFileListener = nullptr;

  TGSDKManager::m_TUPResolutionCallback = nullptr;
  TGSDKManager::m_TUPBarCodeResultCallback = nullptr;

  // 释放条码指针数组
  mfree();
}

/**
 * HID总线错误S
 * @brief OnErrorListener::onHIDError
 * @param errorCode
 * @param errMsg
 */
void OnErrorListener::onHIDError(int errorCode, std::string errMsg) {
  INSTANCE(TGSDKManager).hidListenerError(errorCode, errMsg);
}

/**
 * 写数据进度
 * @brief HIDWriteListener::onResult
 * @param progress
 * @param totalProgress
 * @param completed
 */
void HIDWriteListener::onHIDWriteResult(int progress, long totalProgress,
                                        bool completed) {
  INSTANCE(TGSDKManager)
      .hidWriteDataSuccess(progress, totalProgress, completed);
}

/**
 * 写文件数据错误监听
 * @brief HIDWriteListener::onFailed
 * @param errorCode
 * @param errMsg
 */
void HIDWriteListener::onHIDWriteFailed(int errorCode, string errMsg) {
  INSTANCE(TGSDKManager).hidWriteDataError(errorCode, errMsg);
}

/**
 * 读文件监听
 * @brief ReadFileListener::onFileResult
 * @param filePath
 * @param tag
 * @param progress
 * @param maxProgress
 * @param completed
 */
void ReadFileListener::onHIDReadFileResult(std::string filePath,
                                           std::string tag, int progress,
                                           long maxProgress, bool completed) {
  INSTANCE(TGSDKManager).hidFileReceive(filePath, tag, progress, maxProgress, completed);
}

/**
 * 读文件失败监听
 * @brief ReadFileListener::onFailed
 * @param errorCode
 * @param errMsg
 */
void ReadFileListener::onHIDReadFileFailed(int errorCode, std::string errMsg) {
  INSTANCE(TGSDKManager).hidReadFileError(errorCode, errMsg);
}

/**
 * 接收HID数据
 * @brief FrameListener::onFrame
 * @param cmd
 * @param data
 * @param tag
 */
void FrameListener::onHIDFrameFrame(char cmd, const std::vector<char> &data,
                                    std::string tag) {
  std::string d(data.data());
  INSTANCE(TGSDKManager).hidHidRecFrame(tag, d);
}

/**
 * 接收HID帧数据失败
 * @brief FrameListener::onFailed
 * @param errorCode
 * @param errMsg
 */
void FrameListener::onHIDFrameFailed(int errorCode, std::string errMsg) {
  INSTANCE(TGSDKManager).hidFrameError(errorCode, errMsg);
}

/**
 *  写随机文件开始
 */
void WriteRandomFileListener::onHIDWriteRandomStart() {
  INSTANCE(TGSDKManager).hidWriteRandomFileStart();
}

/**
 * 写随机文件异常
 * @param errorCode
 * @param errMsg
 */
void WriteRandomFileListener::onHIDWriteRandomFailed(int errorCode,
                                                     std::string errMsg) {
  INSTANCE(TGSDKManager).hidWriteRandomFileFailed(errorCode, errMsg);
}

/**
 * 写随机文件完成
 */
void WriteRandomFileListener::onHIDWriteRandomCompleted() {
  INSTANCE(TGSDKManager).hidWriteRandomFileCompleted();
}

/**
 * 读取随机文件
 * @param filePath
 * @param completed
 */
void ReadRandomFileListener::onHIDReadRandomFileResult(std::string filePath,
                                                       bool completed) {
  INSTANCE(TGSDKManager).hidReadRandomFileResult(filePath, completed);
}

void ReadRandomFileListener::onHIDReadRandomCancel(std::string filePath) {
  INSTANCE(TGSDKManager).hidReadRandomCancel(filePath);
}

/**
 * 读取随机文件暂停
 * @param paused
 */
void ReadRandomFileListener::onHIDReadRandomPause(bool paused) {
  INSTANCE(TGSDKManager).hidReadRandomPause(paused);
}

/**
 * 读取随机文件错误
 * @param errorCode
 * @param errMsg
 */
void ReadRandomFileListener::onHIDReadRandomFailed(int errorCode,
                                                   std::string errMsg) {
  INSTANCE(TGSDKManager).hidReadRandomFailed(errorCode, errMsg);
}

/**
 * 停止发送数据回调
 */
void StopDataListener::onHIDStopData() {}

/**
 * 初始化HID
 * @brief SignSDKManager::InitHID
 */
int TGSDKManager::InitHID() {
    std::string m_HidDownloadPath;
#ifdef _WIN32
  // 获取当前程序目录
#ifdef UNICODE
    WCHAR exePath[MAX_PATH] = { 0 };
    HMODULE hModule = GetModuleHandle(NULL);
    auto size = GetModuleFileNameW(hModule, exePath, MAX_PATH);
    if (size == 0) {
        std::wcout << L"获取程序执行路径失败" << std::endl;
        return ERR_OPEN_DEV;
    }

    // 截取只剩下目录
    std::wstring fullPath(exePath);
    std::wstring path = fullPath.substr(0, fullPath.find_last_of(L"\\"));
    path.append(L"\\");
    path.append(L"download");

    // 创建目录
    BOOL result = CreateDirectoryW(path.c_str(), NULL);
    if (!result) {
        DWORD error = GetLastError();
        if (error != ERROR_ALREADY_EXISTS) {
            std::wcout << L"创建目录失败: " << error << std::endl;
            return ERR_OPEN_DEV;
        }
    }
    // 宽字符转多字节
    m_HidDownloadPath = WChar2Ansi(path.c_str());
#else
    // ASCII 字符
    char exePath[MAX_PATH] = { 0 };
    HMODULE hModule = GetModuleHandle(NULL);
    auto size = GetModuleFileNameA(hModule, exePath, MAX_PATH);
    if (size == 0) {
        std::cout << "获取程序执行路径失败" << std::endl;
        return ERR_OPEN_DEV;
    }

    std::string fullPath(exePath);
    std::string path = fullPath.substr(0, fullPath.find_last_of("\\"));
    path.append("\\");
    path.append("download");

    BOOL result = CreateDirectoryA(path.c_str(), NULL);
    if (!result) {
        DWORD error = GetLastError();
        if (error != ERROR_ALREADY_EXISTS) {
            std::cout << "创建目录失败: " << m_HidDownloadPath << ",error code: " << error << std::endl;
            return ERR_OPEN_DEV;
        }
    }
    // 保存HID保存路径
    m_HidDownloadPath = path;
#endif // !UNICODE
#else
    Dl_info dlInfo;
    dladdr((void*)GetDynamicLibraryPath, &dlInfo);
    char* path = realpath(dlInfo.dli_fname, NULL);
    std::string fullPath(path);
    free(path);
    size_t pos = fullPath.find_last_of("/");
    std::string signSDKPath = fullPath.substr(0, pos);
    m_HidDownloadPath = signSDKPath + "/download";
#endif

  // 改用智能指针，创建 hid_interface
  std::shared_ptr<HIDInterfaceImpl> hidInterfacePtr =
      std::make_shared<HIDInterfaceImpl>();
  // 创建 config 的智能指针
  std::shared_ptr<config> configPtr = std::make_shared<config>();
  configPtr->addDownloadDir(m_HidDownloadPath)
      ->addBodyLength(ALLOW_LENGTH)
      ->addFutureID(FUTURE_ID)
      ->addVendorID(0x2207)
      ->addProductId(0x0009);

  // 创建 hid_engine，该类为hid通讯核心类
  m_pHidEngine = std::make_unique<hid_engine>(hidInterfacePtr, configPtr);

  // 监听通讯异常，断开连接
  m_OnErrorListener = std::make_shared<OnErrorListener>();
  m_pHidEngine->setOnHIDErrorListener(
      std::weak_ptr<OnErrorListener>(m_OnErrorListener));

  // 获取文本传输数据
  m_FrameListener = std::make_shared<FrameListener>();
  m_pHidEngine->setOnHIDFrameListener(
      std::weak_ptr<FrameListener>(m_FrameListener));

  // 监听读文件
  m_ReadFileListener = std::make_shared<ReadFileListener>();
  m_pHidEngine->setOnHIDReadFileListener(
      std::weak_ptr<ReadFileListener>(m_ReadFileListener));

  // 监听中断
  m_StopDataListener = std::make_shared<StopDataListener>();
  m_pHidEngine->setOnHIDStopListener(
      std::weak_ptr<StopDataListener>(m_StopDataListener));

  // 监听上位机写数据状态
  m_WriteListener = std::make_shared<HIDWriteListener>();

  // 写随机文件监听器
  m_WriteRandomFileListener = std::make_shared<WriteRandomFileListener>();

  // 读随机文件监听器
  m_ReadRandomFileListener = std::make_shared<ReadRandomFileListener>();
  m_pHidEngine->setOnReadRandomFileListener(
      std::weak_ptr<ReadRandomFileListener>(m_ReadRandomFileListener));

  return ERR_SUCCESS;
}

/**
 * 初始化，将外部的函数指针内部保存
 * @brief TGSDKManager::Init
 * @param l
 * @return
 */
int TGSDKManager::Init(TG_OnHIDListener l1, TG_OnFrameListener l2,
                       TG_OnReadFileListener l3) {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  TGSDKManager::m_TG_OnHIDListener = l1;
  TGSDKManager::m_TG_OnFrameListener = l2;
  TGSDKManager::m_TG_ReadFileListener = l3;
  return InitHID();
}

/**
 * 反初始化
 * @brief TGSDKManager::UInit
 * @return
 */
int TGSDKManager::UInit() {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  TGSDKManager::m_TG_WriteFileListener = nullptr;
  TGSDKManager::m_TG_OnFrameListener = nullptr;
  TGSDKManager::m_TG_ReadFileListener = nullptr;
  TGSDKManager::m_TG_OnHIDListener = nullptr;
  TGSDKManager::m_TG_WriteRandomFileListener = nullptr;
  TGSDKManager::m_TG_ReadRandomFileListener = nullptr;
  return ERR_SUCCESS;
}

/**
 * 打开设备
 * @brief TGSDKManager::OpenDev
 * @param vendor_id
 * @param product_id
 * @return
 */
int TGSDKManager::OpenDev(unsigned short vendor_id, unsigned short product_id) {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  if (!m_bDevConn && m_pHidEngine) {
    if (m_pHidEngine->open(vendor_id, product_id) == 0) {
      m_bDevConn = true;
    } else {
      m_bDevConn = false;
    }
  }

  return m_bDevConn ? ERR_SUCCESS : ERR_OPEN_DEV;
}

/**
 * 打开相机
 * @brief TGSDKManager::OpenCamera
 * @return
 */
int TGSDKManager::OpenCamera() {
  const char *data = PackageCommon(OPEN_CAMERA);
  int size = strlen(data);
  std::string tag(OPEN_CAMERA);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 关闭相机
 * @brief TGSDKManager::CloseCamera
 * @return
 */
int TGSDKManager::CloseCamera() {
  const char *data = PackageCommon(CLOSE_CAMERA);
  int size = strlen(data);
  std::string tag(CLOSE_CAMERA);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 开启解码
 * @brief TGSDKManager::StartDecode
 * @param fnBarcodeResultCallback
 * @return
 */
int TGSDKManager::StartDecode(
    TUP_Barcode_Result_Callback fnBarcodeResultCallback) {
  TGSDKManager::m_TUPBarCodeResultCallback = fnBarcodeResultCallback;
  const char* data = PackageCommon(START_DECOCE);
  int size = strlen(data);
  std::string tag(START_DECOCE);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 关闭解码
 * @brief TGSDKManager::StopDecode
 * @return
 */
int TGSDKManager::StopDecode() {
    const char* data = PackageCommon(STOP_DECODE);
    int size = strlen(data);
    std::string tag(STOP_DECODE);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 设置条码模式
 * @brief TGSDKManager::SetBarMode
 * @param splitMode
 * @return
 */
int TGSDKManager::SetBarMode(int splitMode, int appendSplitMode) {
    const char* data =
      PacketSetBarMode(SET_BARCODE_MODE, splitMode, appendSplitMode);
    int size = strlen(data);
    std::string tag(SET_BARCODE_MODE);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 条码码与码之间的延迟
 * @brief TGSDKManager::SetBarCodeDelay
 * @param delay
 * @return
 */
int TGSDKManager::SetBarCodeDelay(float delay) {
    const char* data = PacketSetBarCodeDelay(SET_BARCODE_DELAY, delay);
    int size = strlen(data);
    std::string tag(SET_BARCODE_DELAY);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 设置自动清理
 * @brief TGSDKManager::SetAutoClear
 * @param time
 * @return
 */
int TGSDKManager::SetAutoClear(float time) {
    const char* data = PacketSetAutoClear(SET_AUTO_CLEAR, time);
    int size = strlen(data);
    std::string tag(SET_BARCODE_DELAY);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 关闭自动清理
 * @brief TGSDKManager::StopAutoClear
 * @return
 */
int TGSDKManager::StopAutoClear() {
  const char* data = PackageCommon(STOP_AUTO_CLEAR);
  int size = strlen(data);
  std::string tag(STOP_AUTO_CLEAR);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 设置码与码之间的回车个数
 * @brief TGSDKManager::SetEnterCount
 * @param count
 * @return
 */
int TGSDKManager::SetEnterCount(int count) {
    const char* data = PacketSetEnterCount(SET_ENTER_COUNT, count);
    int size = strlen(data);
    std::string tag(SET_ENTER_COUNT);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 设置追加字符
 * @brief TGSDKManager::SetAppendChars
 * @param pos
 * @param chars
 * @return
 */
int TGSDKManager::SetAppendChars(int pos, char *chars) {
  const char* data = PacketSetAppendChars(SET_APPEND_CHARS, pos, chars);
  int size = strlen(data);
  std::string tag(SET_APPEND_CHARS);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 设置追溯码分割方式
 * @brief TGSDKManager::SetTraceCodeSplit
 * @param traceCodeSplit
 * @return
 */
int TGSDKManager::SetTraceCodeSplit(int traceCodeSplit) {
    const char* data = PacketTraceCodeSplit(SET_TRACE_CODE_SPLIT, traceCodeSplit);
    int size = strlen(data);
    std::string tag(SET_TRACE_CODE_SPLIT);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 语音播报模式
 * @brief TGSDKManager::SetTraceCodeSplit
 * @param traceCodeSplit
 * @return
 */
int TGSDKManager::SetVoiceSpeechMode(int voiceSpeechMode)
{
    const char* data = PacketSetVoiceSpeechMode(SET_VOICE_SPEECH_MODE, voiceSpeechMode);
    int size = strlen(data);
    std::string tag(SET_VOICE_SPEECH_MODE);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 获取分辨率
 * @brief TGSDKManager::GetResolution
 * @param res
 * @return
 */
int TGSDKManager::GetResolution(TUP_Resolution_Callback fnResolutionCallback) {
  TGSDKManager::m_TUPResolutionCallback = fnResolutionCallback;
  const char *data = PackageCommon(GET_RESOLUTION);
  int size = strlen(data);
  std::string tag(GET_RESOLUTION);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 设置分辨率
 * @brief TGSDKManager::SetResolution
 * @param width
 * @param height
 * @return
 */
int TGSDKManager::SetResolution(int width, int height) {
  const char *data = PacketResolution(SET_RESOLUTION, width, height);
  int size = strlen(data);
  std::string tag(SET_RESOLUTION);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 开启Code128
 * @brief TGSDKManager::EnableCode128
 * @return
 */
int TGSDKManager::EnableCode128() {
  const char *data =  PackageCommon(ENABLE_CODE_128);
  int size = strlen(data);
  std::string tag(ENABLE_CODE_128);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 关闭Code128
 * @brief TGSDKManager::DisableCode128
 * @return
 */
int TGSDKManager::DisableCode128() {
    const char* data = PackageCommon(DISABLE_CODE_128);
    int size = strlen(data);
    std::string tag(DISABLE_CODE_128);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 开启QR码
 * @brief TGSDKManager::EnableQR
 * @return
 */
int TGSDKManager::EnableQR() {
    const char* data = PackageCommon(ENABLE_QR);
  int size = strlen(data);
  std::string tag(ENABLE_QR);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 关闭 QR码
 * @brief TGSDKManager::DisableQR
 * @return
 */
int TGSDKManager::DisableQR() {
    const char* data = PackageCommon(DISABLE_QR);
  int size = strlen(data);
  std::string tag(DISABLE_QR);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 开启DM码
 * @brief TGSDKManager::EnableDM
 * @return
 */
int TGSDKManager::EnableDM() {
    const char* data = PackageCommon(ENABLE_DM);
    int size = strlen(data);
    std::string tag(ENABLE_DM);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 关闭DM码
 * @brief TGSDKManager::DisableDM
 * @return
 */
int TGSDKManager::DisableDM() {
    const char* data = PackageCommon(DISABLE_DM);
    int size = strlen(data);
    std::string tag(DISABLE_DM);
    return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 恢复默认参数
 * @brief TGSDKManager::ResetParams
 * @return
 */
int TGSDKManager::ResetParams() {
  const char *data = PackageCommon(RESET_PARAMS);
  int size = strlen(data);
  std::string tag(RESET_PARAMS);
  return WriteData(data, size, tag.c_str(), tag.size());
}

/**
 * 关闭设备
 * @brief TGSDKManager::CloseDev
 * @return
 */
int TGSDKManager::CloseDev() {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  int ret = -1;
  if (m_bDevConn && m_pHidEngine) {
    ret = m_pHidEngine->close();
    m_bDevConn = false;
  }

  return ret == 0 ? ERR_SUCCESS : ERR_DEVICE_FAIL;
}

/**
 * 释放条码数组内存
 * @brief TGSDKManager::mfree
 */
int TGSDKManager::mfree() {
  if (list != nullptr) {
    for (int i = 0; i < arraySize; i++) {
      if (list[i]->barcode != NULL) {
        free(list[i]->barcode);
      }
      free(list[i]);
    }
    free(list);
    list = nullptr;
  }
  return ERR_SUCCESS;
}

/**
 * 写 ACK 恢复
 * @brief TGSDKManager::WriteDataInner
 * @param data
 * @param size
 * @param tag
 * @param tagSize
 * @return
 */
int TGSDKManager::WriteACK(const char *data, int size, const char *tag,
                           int tagSize) {
  std::lock_guard<std::mutex> lock(m_gMutex);
  if (!m_bDevConn || !m_pHidEngine) {
    return ERR_OPEN_DEV;
  }

  return m_pHidEngine->WriteACK(data, size, tag, tagSize, CMD_ACK) == true
             ? ERR_SUCCESS
             : ERR_DEVICE_FAIL;
}

/**
 * 写文本数据
 * @brief TGSDKManager::WriteData
 * @param data
 * @param size
 * @param tag
 * @param tagSize
 * @return
 */
int TGSDKManager::WriteData(const char *data, int size, const char *tag,
                            int tagSize) {

  std::lock_guard<std::mutex> lock(m_gMutex);
  if (!m_bDevConn || !m_pHidEngine) {
    return ERR_OPEN_DEV;
  }

  TGSDKManager::m_TG_WriteFileListener = nullptr;
  return m_pHidEngine->writeDataSync(data, size, tag, tagSize, CMD_TEXT);
}

/**
 * 写文本数据，异步回调
 * @brief TGSDKManager::WriteData2
 * @param data
 * @param size
 * @param tag
 * @param tagSize
 * @param l
 */
void TGSDKManager::WriteData2(const char *data, int size, const char *tag,
                              int tagSize, TG_WriteFileListener l) {
  std::lock_guard<std::mutex> lock(m_gMutex);
  if (!m_bDevConn && !m_pHidEngine) {
    if (l != nullptr) {
      l(ERR_WRITEDATA, (char *)std::string("Device not connected.").c_str(), 0,
        0, false);
    }
    return;
  }

  TGSDKManager::m_TG_WriteFileListener = l;
  m_pHidEngine->writeData(data, size, tag, tagSize, CMD_TEXT,
                          std::weak_ptr<OnHIDWriteListener>(m_WriteListener));
}

/**
 * 写文件
 * @brief TGSDKManager::WriteFile
 * @param filePath
 * @param tag
 * @param tagSize
 * @param l
 */
void TGSDKManager::WriteFile(const char *filePath, const char *tag, int tagSize,
                             TG_WriteFileListener l) {
  std::lock_guard<std::mutex> lock(m_gMutex);
  if (!m_bDevConn && !m_pHidEngine) {
    return;
  }

  TGSDKManager::m_TG_WriteFileListener = l;
  m_pHidEngine->writeFile(std::string(filePath), tag, tagSize,
                          std::weak_ptr<OnHIDWriteListener>(m_WriteListener));
}

/**
 * 写随机文件
 * @brief TGSDKManager::WriteRandomFile
 * @param filePath
 * @param tag
 * @param tagSize
 * @param l
 */
void TGSDKManager::WriteRandomFile(const char *filePath, int fileExtension,
                                   TG_WriteRandomFileListener l) {
  std::lock_guard<std::mutex> lock(m_gMutex);
  if (!m_bDevConn || m_pHidEngine == nullptr) {
    return;
  }

  TGSDKManager::m_TG_WriteRandomFileListener = l;
  m_pHidEngine->writeRandomFile(
      std::string(filePath), fileExtension,
      std::weak_ptr<OnHIDWriteRandomFileListener>(m_WriteRandomFileListener));
}

/**
 * 停止发送数据
 * @brief TGSDKManager::Stop
 * @return
 */
int TGSDKManager::Stop() {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  if (!m_bDevConn) {
    return ERR_OPEN_DEV;
  }

  m_pHidEngine->stop(std::weak_ptr<OnHIDStopDataListener>(m_StopDataListener));
  return ERR_SUCCESS;
}

void TGSDKManager::cancelRandomFile() {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  if (!m_bDevConn || m_pHidEngine == nullptr) {
    return;
  }
  m_pHidEngine->cancelRandomFile();
}

void TGSDKManager::pause() {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  if (!m_bDevConn || m_pHidEngine == nullptr) {
    return;
  }
  m_pHidEngine->pause();
}

void TGSDKManager::resume() {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  if (!m_bDevConn || m_pHidEngine == nullptr) {
    return;
  }
  m_pHidEngine->resume();
}

/**
 * 停止随机文件
 */
void TGSDKManager::stopRandomFile() {
  std::lock_guard<std::mutex> lock(g_MutexVar);
  if (!m_bDevConn || m_pHidEngine == nullptr) {
    return;
  }
  m_pHidEngine->stopRandomFile();
}

/**
 * 监听HID总线错误
 * @brief TGSDKManager::hidListenerError
 * @param errorCode
 * @param errMsg
 */
void TGSDKManager::hidListenerError(int errorCode, std::string errMsg) {
  // TODO 写数据失败时，需要重置 ack 状态，否则不能再次发起数据
  INSTANCE(constants).setAckFlag(true);
  if (m_TG_WriteFileListener != nullptr) {
    m_TG_WriteFileListener(errorCode, (char *)errMsg.c_str(), 0, 0, false);
  }
}

void TGSDKManager::hidWriteDataSuccess(int progress, long totalProgress,
                                       bool completed) {
  // 写数据完成时，需要重置 ack 标志
  if (completed) {
    INSTANCE(constants).setAckFlag(true);
  }
  if (m_TG_WriteFileListener != nullptr) {
    m_TG_WriteFileListener(ERR_SUCCESS, NULL, progress, totalProgress,
                           completed);
  }
}

void TGSDKManager::hidWriteDataError(int errorCode, std::string errMsg) {
  // TODO 写数据失败时，需要重置 ack 状态，否则不能再次发起数据
  INSTANCE(constants).setAckFlag(true);
  if (m_TG_WriteFileListener != nullptr) {
    m_TG_WriteFileListener(errorCode, (char *)errMsg.c_str(), 0, 0, false);
  }
}

void TGSDKManager::hidFileReceive(std::string filePath, std::string tag, int progress,
                                  long maxProgress, bool completed) {
  if (completed) {
    // TODO 读取到上位机的文件时，需要回复 ack
    char d[] = {0x41, 0x43, 0x4B};
    char t[] = {0x41, 0x43, 0x4B};
    int ret = WriteACK(d, 3, t, 3);
    std::cout << "接收上位机文件，回复ACK通知上位机已经收到" << std::endl;
    INSTANCE(constants).setAckFlag(true);
    if (ret != ERR_SUCCESS) {
      if (m_TG_ReadFileListener != nullptr) {
        std::string errorMsg("Write ACK error.");
        m_TG_ReadFileListener(ERR_WRITEDATA, (char *)errorMsg.c_str(), NULL,
                              NULL, 0, 0, false);
      }
    }
  }

  if (m_TG_ReadFileListener != nullptr) {
    m_TG_ReadFileListener(ERR_SUCCESS, nullptr, (char*)filePath.c_str(),
        (char*)tag.c_str(), progress, maxProgress,
                          completed);
  }
}

void TGSDKManager::hidReadFileError(int errorCode, std::string errMsg) {
  INSTANCE(constants).setAckFlag(true);
  if (m_TG_ReadFileListener != nullptr) {
    m_TG_ReadFileListener(errorCode, (char*)errMsg.c_str(), NULL, NULL, 0, 0,
                          false);
  }
}

/**
 * 接收下位机HID数据
 * @brief TGSDKManager::hidHidRecFrame
 * @param tag
 * @param msg
 */
void TGSDKManager::hidHidRecFrame(std::string tag, std::string msg) {
  // TODO 当我们收到下位机的数据包后，需要通知下位机 ACK 数据包
  char d[] = {0x41, 0x43, 0x4B};
  char t[] = {0x41, 0x43, 0x4B};
  int ret = WriteACK(d, 3, t, 3);
  std::cout << "接收下位机帧数据 tag: " << tag << std::endl;
  std::string ack("ACK");
  if (ret == ERR_SUCCESS) {
    if (ack != tag) {
      std::string getResolutionStr(GET_RESOLUTION);
      if (tag == getResolutionStr) { // 获取分辨率
        std::string resolution;
        int nRet = ParseResolution(msg.c_str() , resolution);
        if (nRet == 0) {
          if (m_TUPResolutionCallback != nullptr) {
            m_TUPResolutionCallback(TUP_ERR_SUCCESS, NULL,
                                    (char*)resolution.c_str());
          }
        }
      } else if (tag == "CodeBarData") { // 解码回调
        // 解析下位机数据
        std::vector<std::string> barcodes;
        int splitMode;
        int appendSplitMode;
        float delay;
        int enterCount;
        int nRet = ParseBarCodes(msg.c_str(), barcodes, splitMode,
                                 appendSplitMode, delay, enterCount);
        if (nRet == 0) {
          int size = barcodes.size();
          // 插入报码数据
          mfree();
          // 创建条码数组
          list = (BARCODE_BEAN **)malloc(size * sizeof(BARCODE_BEAN *));
          if (list == NULL) {
            return;
          }
          for (int i = 0; i < size; i++) {
            std::string barcode = barcodes[i];
            BARCODE_BEAN *bean = (BARCODE_BEAN *)malloc(sizeof(BARCODE_BEAN));
            if (bean == NULL) {
              mfree();
              return;
            }
            int barcodeLength = barcode.size();
            bean->barcode = (char *)malloc(barcodeLength + 1);
            memset(bean->barcode, 0, barcodeLength + 1);
            memcpy(bean->barcode, barcode.c_str(),
                   barcode.size());
            bean->delay = delay;
            bean->enterCount = enterCount;
            bean->splitMode = splitMode;
            bean->appendSplitMode = appendSplitMode;
            list[i] = bean;
          }

          if (m_TUPBarCodeResultCallback != nullptr) {
            m_TUPBarCodeResultCallback(ERR_SUCCESS, NULL, list, size);
          }
        }
      }
    }
  } else {
    if (ack != tag) {
      if (m_TUPBarCodeResultCallback != nullptr) {
        std::string errorMsg("Barcode data error.");
        m_TUPBarCodeResultCallback(ERR_SUCCESS, (char *)errorMsg.c_str(), NULL,
                                   0);
      }
    }
  }
}

/**
 * 接收下位机HID数据错误
 * @brief TGSDKManager::hidFrameError
 * @param errorCode
 * @param errMsg
 */
void TGSDKManager::hidFrameError(int errorCode, std::string errMsg) {
  INSTANCE(constants).setAckFlag(true);
  //  if (m_TG_OnFrameListener != nullptr) {
  //    m_TG_OnFrameListener(errorCode, errMsg.toUtf8().data(), NULL, NULL);
  //  }
  if (m_TUPBarCodeResultCallback != nullptr) {
    std::string errorMsg("Barcode data error.");
    m_TUPBarCodeResultCallback(ERR_SUCCESS, (char *)errorMsg.c_str(), NULL, 0);
  }
}

/**
 * 写随机文件开始
 */
void TGSDKManager::hidWriteRandomFileStart() {
  if (m_TG_WriteRandomFileListener != nullptr) {
    m_TG_WriteRandomFileListener(
        ERR_SUCCESS, (char *)std::string("Write Random start").c_str(), true,
        false);
  }
}

/**
 * 写随机文件错误
 * @param errorCode
 * @param errMsg
 */
void TGSDKManager::hidWriteRandomFileFailed(int errorCode, std::string errMsg) {
  // 写随机文件失败时重置 ack
  INSTANCE(constants).setAckFlag(true);
  if (m_TG_WriteRandomFileListener != nullptr) {
    m_TG_WriteRandomFileListener(errorCode, (char*)errMsg.c_str(), false,
                                 false);
  }
}

/**
 * 写随机文件完成
 */
void TGSDKManager::hidWriteRandomFileCompleted() {
  // 写随机文件完成时重置 ack
  INSTANCE(constants).setAckFlag(true);
  if (m_TG_WriteRandomFileListener != nullptr) {
    m_TG_WriteRandomFileListener(
        ERR_SUCCESS, (char *)std::string("Write Random complete").c_str(),
        false, true);
  }
}

/**
 * 上位机发送随机文件，比如视频、二进制文件
 * @param filePath
 * @param completed
 */
void TGSDKManager::hidReadRandomFileResult(std::string filePath,
                                           bool completed) {
  INSTANCE(constants).setAckFlag(true);
  if (completed) {
    char d[] = {0x41, 0x43, 0x4B};
    char t[] = {0x41, 0x43, 0x4B};
    int ret = WriteACK(d, 3, t, 3);
    if (ret == ERR_SUCCESS) {
      if (m_TG_ReadRandomFileListener != nullptr) {
        m_TG_ReadRandomFileListener(ERR_SUCCESS, (char *)filePath.c_str(), NULL,
                                    0, 0, 1);
      }
    } else {
      if (m_TG_ReadRandomFileListener != nullptr) {
        std::string errorMsg("Write ACK error.");
        m_TG_ReadRandomFileListener(ERR_WRITEDATA, (char *)errorMsg.c_str(),
                                    NULL, 0, 0, 0);
      }
    }
  } else {
    if (m_TG_ReadRandomFileListener != nullptr) {
      m_TG_ReadRandomFileListener(ERR_SUCCESS, (char *)filePath.c_str(), NULL,
                                  0, 0, completed);
    }
  }
}

/**
 * 上位机取消发送随机文件
 * @param filePath
 */
void TGSDKManager::hidReadRandomCancel(std::string filePath) {
  INSTANCE(constants).setAckFlag(true);
  char d[] = {0x41, 0x43, 0x4B};
  char t[] = {0x41, 0x43, 0x4B};
  WriteACK(d, 3, t, 3);
  if (m_TG_ReadRandomFileListener != nullptr) {
    m_TG_ReadRandomFileListener(ERR_SUCCESS, (char *)filePath.c_str(), NULL, 0,
                                1, 0);
  }
}

/**
 * 上位机暂停发送随机文件，可能有其他业务要打断
 * @param paused
 */
void TGSDKManager::hidReadRandomPause(bool paused) {
  INSTANCE(constants).setAckFlag(true);
  char d[] = {0x41, 0x43, 0x4B};
  char t[] = {0x41, 0x43, 0x4B};
  WriteACK(d, 3, t, 3);
  if (m_TG_ReadRandomFileListener != nullptr) {
    m_TG_ReadRandomFileListener(ERR_SUCCESS, NULL, NULL, paused, 0, 0);
  }
}

/**
 * 上位机发送的随机文件发生错误
 * @param errorCode
 * @param errMsg
 */
void TGSDKManager::hidReadRandomFailed(int errorCode, std::string errMsg) {
  INSTANCE(constants).setAckFlag(true);
  char d[] = {0x41, 0x43, 0x4B};
  char t[] = {0x41, 0x43, 0x4B};
  WriteACK(d, 3, t, 3);
  if (m_TG_ReadRandomFileListener != nullptr) {
    m_TG_ReadRandomFileListener(errorCode, (char *)errMsg.c_str(), NULL, 0, 0,
                                0);
  }
}
